//
//  FXBuddyList.m
//  FetionDataStructure
//
//  Created by Ronnie on 08-12-2.
//  Copyright 2008 __MyCompanyName__. All rights reserved.
//

#import "FXDataCenter.h"


@implementation FXDataCenter


- (id)initFromNet
{
	self = [super init];
	[self _getMyselfInfo];
	[self _getMyFriendsInfo];
	return self;
}

- (FXTreeNode*)getMyBuddyList
{
	return myBuddyList;
}

// get the all info thought network
- (void)_getMyselfInfo
{
	myId = atol(fx_get_usr_uid());
	myState = fx_get_user_state();
	myExpiresTime = fx_get_expirestime();
	myPersonalInfo = fx_data_get_PersonalInfo();
	
	myNickName = [[NSString stringWithUTF8String:myPersonalInfo->nickname?myPersonalInfo->nickname:""] retain];
	myImpresa = [[NSString stringWithUTF8String:myPersonalInfo->impresa?myPersonalInfo->impresa:""] retain];
}

- (void)_getMyFriendsInfo
{
	// create the root node of buddy list
	myBuddyList = [[FXTreeNode alloc] initGroupNodeWithId:-1 name:nil parent:nil];
	
	// get all the groups info
	Fetion_Group *group = NULL;
	DList *group_list = (DList *)fx_get_group();
	
	while(group_list)
	{
		group = (Fetion_Group *) group_list->data;
		
		if(group) { 
			//fprintf(stderr, "Insert the group %d : %s to the buddy list!\n",group->id, group->name);
			FXTreeNode* groupNode = [[FXTreeNode alloc] initGroupNodeWithId:group->id name:[NSString stringWithUTF8String:group->name] parent:myBuddyList];
			[myBuddyList insertChild:groupNode atIndex:[myBuddyList numberOfChildren]];
		}
		group_list = d_list_next(group_list);
	}
	
	// Insert all the buddies
	const Fetion_Account *account = fx_get_first_account();
	while(account) 
	{		
		FXUserInfo* user = [FXUserInfo fxUserWithAccount:account];
		if ( [user groupId] > 0 ) {
			FXTreeNode* groupP = nil;
			for( int i=0; i<[myBuddyList numberOfChildren]; i++ )
			{
				groupP = [myBuddyList childAtIndex:i];
				if ([groupP groupId] == [user groupId]) {
					break;
				}
			}
			//FXTreeNode* groupP = [[myBuddyList childAtIndex:[user groupId]-1] retain];
			FXTreeNode* leafNode = [[FXTreeNode alloc] initLeafNodeWithUserInfo:user parent:groupP];
			[groupP insertChild:leafNode atIndex:[groupP numberOfChildren]];
		}
		else
		{
			// this means that this user belongs to no group
			FXTreeNode* leafNode = [[FXTreeNode alloc] initLeafNodeWithUserInfo:user parent:myBuddyList];
			[myBuddyList insertChild:leafNode atIndex:[myBuddyList numberOfChildren]];
		}
		account = fx_get_next_account(account);
	}
	
	[myBuddyList recursiveSortChildren];
}

- (void) dealloc
{
	if (myNickName) {
		[myNickName release];
	}
	if (myImpresa) {
		[myImpresa release];
	}
	if (myBuddyList) {
		[myBuddyList release];
	}
	[super dealloc];
}


- (FXTreeNode*)getFXTreeNodeById:(long)uid
{
	for( int i=0; i<[myBuddyList numberOfChildren]; i++ )
	{
		FXTreeNode* node_1 = [myBuddyList childAtIndex:i];
		if ([node_1 isLeaf]) {
			if ([[node_1 getUserInfo] userID] == uid) {
				return node_1;
			}
		}
		else {
			for( int j=0; j<[node_1 numberOfChildren]; j++ )
			{
				FXTreeNode* node_2 = [node_1 childAtIndex:j];
				if ([node_2 isLeaf]) {
					if ([[node_2 getUserInfo] userID] == uid) {
						return node_2;
					}
				}
			}
		}
	}
	return nil;
}

- (void)addGroupById:(int)gid
{
	Fetion_Group *group = NULL;
	DList *group_list = (DList *)fx_get_group();
	
	while(group_list)
	{
		group = (Fetion_Group *) group_list->data;
		
		if(group->id == gid) { 
			//fprintf(stderr, "Insert the group %d : %s to the buddy list!\n",group->id, group->name);
			FXTreeNode* groupNode = [[FXTreeNode alloc] initGroupNodeWithId:group->id name:[NSString stringWithUTF8String:group->name] parent:myBuddyList];
			[myBuddyList insertChild:groupNode atIndex:[myBuddyList numberOfChildren]];
			break;
		}
		group_list = d_list_next(group_list);
	}
	[myBuddyList sortChildren];
}

- (void)addBuddy:(long)uid toGroup:(int)gid
{
	const Fetion_Account *account = fx_get_account_by_id(uid);
	int groupId = fx_get_account_group_id(account);
	FXTreeNode* group = [self getGroupNodeById:groupId];
	FXUserInfo* user = [FXUserInfo fxUserWithAccount:account];
	FXTreeNode* leafNode = [[FXTreeNode alloc] initLeafNodeWithUserInfo:user parent:group];
	[group insertChild:leafNode atIndex:[group numberOfChildren]];
	[group sortChildren];
}

- (FXTreeNode*)getGroupNodeById:(int)gid
{
	for( int i=0; i<[myBuddyList numberOfChildren]; i++ )
	{
		FXTreeNode* node_1 = [myBuddyList childAtIndex:i];
		if ([node_1 isGroup]) {
			if ([node_1 groupId] == gid) {
				return node_1;
			}
		}
	}
	return nil;
}

- (FXTreeNode*)updateInfoById:(long)uid
{
	FXTreeNode* node = [self getFXTreeNodeById:uid];
	[[node getUserInfo] updateSelfInfo];
	return node;
	/*bool hasUpdated = false;
	for( int i=0; i<[myBuddyList numberOfChildren]; i++ )
	{
		FXTreeNode* node_1 = [myBuddyList childAtIndex:i];
		if (!hasUpdated) {
			if ([node_1 isLeaf]) {
				if ([[node_1 getUserInfo] userID] == uid) {
					[[node_1 getUserInfo] updateSelfInfo];
					hasUpdated = true;
					return node_1;
				}
			}
			else {
				for( int j=0; j<[node_1 numberOfChildren]; j++ )
				{
					if (!hasUpdated) {
						FXTreeNode* node_2 = [node_1 childAtIndex:j];
						if ([node_2 isLeaf]) {
							if ([[node_2 getUserInfo] userID] == uid) {
								[[node_2 getUserInfo] updateSelfInfo];
								hasUpdated = true;
								return node_2;
							}
						}
					}
					else {
						break;
					}
				}
			}
		}
		else
		{
			break;
		}
	}*/
}

- (NSString*)getMyNickName
{
	return myNickName;
}

- (NSString*)getMyImpresa
{
	return myImpresa;
}

- (void)changeHostImpresaTo:(NSString*)newImpresa
{
	fx_set_user_impresa([newImpresa UTF8String], NULL, NULL);
}

- (int)getMyStatus
{
	return myState;
}

- (void)changeHostStatusTo:(int)status
{
	fx_set_user_state(status, NULL, NULL, NULL);
}


- (void)PrintBuddyList
{
	[myBuddyList PrintTreeNode];
}


- (id)copyWithZone:(NSZone *)zone {
	return [self retain];
}

@end
